<?php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Userfiles;
use App\Models\Userfolders;
use Illuminate\Http\Request;

class UserfilesController extends Controller {

	public function __construct() {
		$this->middleware('admin');
	}

	public function getIndex() {
		return view('admin/userfiles/index');
	}

	public function getPageRows(Request $request) {
		$user_id = session('token')['user_id'];

		$f_id = intval($request->input('f_id'));
		$page = to_limit_lng($request->input('page'), 1);
		$limit = to_limit_lng($request->input('limit'), 1);
		$offset = ($page - 1) * $limit;

		$data['folder'] = Userfolders::find($f_id);
		$data['folder_path'] = $this->getFolderPath($f_id);

		$fold_cnt = Userfolders::where('user_id', $user_id)->where('f_id', $f_id)->count();
		$file_cnt = Userfiles::where('user_id', $user_id)->where('folder_id', $f_id)->count();

		$fold_pages = ceil($fold_cnt / $limit);
		$total_rows = $fold_cnt + $file_cnt;

		$data['page'] = $page;
		$data['total_rows'] = $total_rows;
		$data['page_count'] = ceil($total_rows / $limit);

		$folder_rows = Userfolders::where('user_id', $user_id)->where('f_id', $f_id)->orderBy('sort', 'ASC')->skip($offset)->take($limit)->get();
		$data['folder_rows'] = $folder_rows;

		$file_rows = [];
		$residue = $limit - count($folder_rows);
		if ($residue > 0) {
			$offset = to_limit_lng(($page - 1) * $limit - $fold_cnt);
			$file_rows = Userfiles::where('user_id', $user_id)->where('folder_id', $f_id)->orderBy('title', 'ASC')->skip($offset)->take($residue)->get();
		}
		$data['file_rows'] = $file_rows;
		return $this->response($data);
	}

	private function getFolderPath($id, $ids = []) {
		array_push($ids, $id);
		$row = Userfolders::find($id);
		if (empty($row)) {
			return Userfolders::wherein('id', $ids)->get();
		} else {
			array_push($ids, $row->f_id);
			return $this->getFolderPath($row->f_id, $ids);
		}
	}

	public function postAddFolder(Request $request) {
		$user_id = session('token')['user_id'];
		$f_id = intval($request->input('f_id'));
		$name = safe($request->input('name'));

		$rows = Userfolders::select('name')->where('user_id', $user_id)->where('f_id', $f_id)->get();
		$name = $this->getNewName(array_values(array_dot($rows->toArray())), $name);
		$sort = Userfolders::where(['user_id' => $user_id, 'f_id' => $f_id])->max('sort') + 10;

		$row = new Userfolders;
		$row->user_id = $user_id;
		$row->f_id = $f_id;
		$row->sort = $sort;
		$row->name = $name;
		$row->save();

		return $this->response($row);
	}

	public function postRenFolder(Request $request) {
		$user_id = session('token')['user_id'];
		$id = intval($request->input('id'));
		$name = safe($request->input('name'));
		if (empty($name)) {
			return $this->error('无效的文件夹');
		}
		$row = Userfolders::where('user_id', $user_id)->find($id);
		if (empty($row)) {
			return $this->error('无效的文件夹');
		}
		if ($name == $row->name) {
			return $this->response($row);
		}
		$f_id = $row['f_id'];
		$rows = Userfolders::select('name')->where(['user_id' => $user_id, 'f_id' => $f_id])->get();
		$name = $this->getNewName(array_values(array_dot($rows->toArray())), $name);
		$row->name = $name;
		if ($row->save()) {
			return $this->response($row);
		}
		return $this->error('操作失败');
	}

	private function getNewName($arr, $name, $n = 1) {
		if (in_array($name, $arr)) {
			if (preg_match("/(.+)\(\d+\)$/i", $name, $matches)) {
				$new_name = $matches[1] . '(' . $n . ')';
			} else {
				$new_name = $name . '(' . $n . ')';
			}
			if (in_array($new_name, $arr)) {
				return $this->getNewName($arr, $name, ++$n);
			}
			return $new_name;
		}
		return $name;
	}

	public function postRemoveFolder(Request $request) {
		$user_id = session('token')['user_id'];
		$id = intval($request->input('id'));
		$row = Userfolders::where('user_id', $user_id)->find($id);
		if (empty($row)) {
			return $this->error('无效的文件夹');
		}
		$f_id = $row->f_id;

		$cnt = Userfolders::where('f_id', $id)->count();
		if ($cnt > 0) {
			return $this->error('请先删除此文件夹下的所有子文件夹');
		}
		if ($row->delete()) {
			Userfiles::where('folder_id', $id)->update(['folder_id' => $f_id]);
			return $this->response($id);
		}
		return $this->error('操作失败');
	}

	public function getFolderZtree() {
		$data = [['id' => 0, 'name' => '全部文件', 'open' => true]];
		$user_id = session('token')['user_id'];
		$query = Userfolders::where('user_id', $user_id);
		$rows = $query->orderBy('f_id', 'ASC')->orderBy('sort', 'ASC')->get();
		foreach ($rows as $row) {
			array_push($data, [
				'id' => $row->id,
				'pId' => $row->f_id,
				'sort' => $row->sort,
				'name' => $row->name,
			]);
		}
		return $this->response($data);
	}

	public function postChangeSortByZtree(Request $request) {
		$source_id = intval($request->input('id'));
		$target_id = intval($request->input('targetId'));
		$move_type = strval($request->input('moveType')); //inner, prev, next

		$source = Userfolders::find($source_id);
		$target = Userfolders::find($target_id);

		switch ($move_type) {
		case 'prev':
			if ($source->sort > $target->sort) {
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->whereBetween('sort', [$target->sort, $source->sort])->increment('sort', 10);
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->where('id', $source_id)->update(['sort' => $target->sort]);
			} else {
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->whereBetween('sort', [$source->sort, $target->sort - 10])->decrement('sort', 10);
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->where('id', $source_id)->update(['sort' => $target->sort - 10]);
			}
			break;
		case 'next':
			if ($source->sort > $target->sort) {
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->whereBetween('sort', [$target->sort + 10, $source->sort])->increment('sort', 10);
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->where('id', $source_id)->update(['sort' => $target->sort + 10]);
			} else {
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->whereBetween('sort', [$source->sort, $target->sort])->decrement('sort', 10);
				$query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
				$query->where('id', $source_id)->update(['sort' => $target->sort]);
			}
			break;
		default:
			break;
		}
		return $this->response('ok');
	}

	public function postUploadFile(Request $request) {
		$user_id = session('token')['user_id'];
		$folder_id = intval($request->input('folder_id'));
		if ($folder_id > 0) {
			$row = Userfolders::where('user_id', $user_id)->find($folder_id);
			if (empty($row)) {
				return $this->error('无效的文件夹');
			}
		}

		if (!$request->hasFile('file')) {
			return $this->error('无效的文件');
		}
		$file = $request->file('file');

		$target_path = 'upload/' . date('Y/m/d/');
		$targetPath = public_path() . '/' . $target_path;
		if (!is_dir($targetPath)) {
			if (!mkdir($targetPath, 0777, 1)) {
				return $this->error('无法建立上传目录');
			}
		}

		$title = $orig_name = safe($request->input('name'));
		$file_type = safe($request->input('type'), 50);
		$file_size = intval($request->input('size'));
		$file_ext = strtolower(get_file_ext($title));

		if (!in_array($file_ext, config('extensions.allowExt'))) {
			return $this->error('上传文件的类型不支持');
		}

		$new_filename = uniqid() . '.' . $file_ext;
		$file->move($targetPath, $new_filename);
		$file1 = $target_path . $new_filename;

		$data = compact('user_id', 'folder_id', 'title', 'file1', 'orig_name', 'file_type', 'file_size', 'file_ext');
		$row = new Userfiles;
		foreach ($data as $key => $val) {
			$row->$key = $val;
		}
		if ($row->save()) {
			return $this->response($row);
		}
		return $this->error('文件上传失败');
	}

	public function getDownloadFile(Request $request) {
		$user_id = session('token')['user_id'];
		$id = intval($request->input('id'));
		$row = Userfiles::where('user_id', $user_id)->find($id);
		if (empty($row)) {
			return response('Invalid Request.', 404);
		}

		$file = $row->file1;
		if (!file_exists($file)) {
			return response('The file specified does not exist.', 404);
		}

		$file_name = iconv('utf-8', 'gb2312', $row->title);
		$file_size = filesize($file);

		Header('Content-type: application/octet-stream');
		Header('Accept-Ranges: bytes');
		Header('Accept-Length: ' . $file_size);
		Header("Content-Disposition: attachment; filename=" . $file_name);

		$fp = fopen($file, 'r+');
		while (!feof($fp)) {
			$file_data = fread($fp, 1024);
			echo $file_data;
		}
		fclose($fp);
	}

	public function getFileInfo(Request $request) {
		$user_id = session('token')['user_id'];
		$id = intval($request->input('id'));

		$row = Userfiles::where('user_id', $user_id)->find($id);
		if (empty($row)) {
			return $this->error('无效的文件');
		}
		$row->file_url = asset($row->file1);
		return $this->response($row);
	}

	public function postRenFile(Request $request) {
		$user_id = session('token')['user_id'];

		$id = intval($request->input('id'));
		$row = Userfiles::where('user_id', $user_id)->find($id);
		if (empty($row)) {
			return $this->error('无效的文件');
		}

		$row->title = safe($request->input('title'));
		if ($row->save()) {
			return $this->response($row);
		}
		return $this->error('操作失败');
	}

	public function postMoveFiles(Request $request) {
		$user_id = session('token')['user_id'];
		$folder_id = intval($request->input('folder_id'));
		if ($folder_id > 0) {
			$row = Userfolders::where('user_id', $user_id)->find($folder_id);
			if (empty($row)) {
				return $this->error('无效的目标文件夹');
			}
		}

		$ids = explode('|', $request->input('ids'));
		if (empty($ids)) {
			return $this->error('参数错误');
		}
		Userfiles::where('user_id', $user_id)->whereIn('id', $ids)->update(['folder_id' => $folder_id]);
		return $this->response($ids);
	}

	public function postRemoveFiles(Request $request) {
		$user_id = session('token')['user_id'];

		$ids = explode('|', $request->input('ids'));
		if (empty($ids)) {
			return $this->error('无效的参数');
		}

		foreach ($ids as $id) {
			$row = Userfiles::where('user_id', $user_id)->find($id);
			if (!empty($row)) {
				$file1 = $row->file1;
				if ($row->delete()) {
					file_exists($file1) && unlink($file1);
				}
			}
		}
		return $this->response($ids);
	}

}